#include "DOFShaderClass.h"

DOFShaderClass::DOFShaderClass(): 
	m_HorizontalBlurShader(0),
	m_VerticalBlurShader(0), 
	m_FinalTexture(0), 
	m_FullScreenWindow(0), 
	m_MergeTextureShader(0),
	m_OriginalTexture(0), 
	m_HorizontalBlurredTexture(0),
	m_VerticalBlurredTexture(0)
{}

bool DOFShaderClass::Initialize(ID3D11Device* i_device, HWND hwnd, int i_screenWidth, int i_screenHeight)
{
	m_HorizontalBlurShader = new HorizontalBlurShaderClass;
	bool result = m_HorizontalBlurShader->Initialize(i_device);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the horizontal blur shader object.", L"Error", MB_OK);
		return false;
	}

	m_VerticalBlurShader = new VerticalBlurShaderClass;
	result = m_VerticalBlurShader->Initialize(i_device);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the vertical blur shader object.", L"Error", MB_OK);
		return false;
	}

	m_HorizontalBlurredTexture = new RenderTextureClass;
	result = m_HorizontalBlurredTexture->Initialize(i_device, i_screenWidth, i_screenHeight, SCREEN_DEPTH, SCREEN_NEAR);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the horizontal blur render to texture object.", L"Error", MB_OK);
		return false;
	}

	m_VerticalBlurredTexture = new RenderTextureClass;
	result = m_VerticalBlurredTexture->Initialize(i_device, i_screenWidth, i_screenHeight, SCREEN_DEPTH, SCREEN_NEAR);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the vertical blur render to texture object.", L"Error", MB_OK);
		return false;
	}

	m_OriginalTexture = new RenderTextureClass;
	result = m_OriginalTexture->Initialize(i_device, i_screenWidth, i_screenHeight, SCREEN_DEPTH, SCREEN_NEAR);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the starting render to texture object.", L"Error", MB_OK);
		return false;
	}

	m_FinalTexture = new RenderTextureClass;
	result = m_FinalTexture->Initialize(i_device, i_screenWidth, i_screenHeight, SCREEN_DEPTH, SCREEN_NEAR);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the output final blur render to texture object.", L"Error", MB_OK);
		return false;
	}

	m_FullScreenWindow = new OrthoWindowClass;
	result = m_FullScreenWindow->Initialize(i_device, i_screenWidth, i_screenHeight);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the full screen ortho window object.", L"Error", MB_OK);
		return false;
	}
	
	m_MergeTextureShader = new MergeTextureShaderClass;
	result = m_MergeTextureShader->Initialize(i_device);
	if(!result)
	{
		MessageBox(hwnd, L"Could not initialize the texture shader object.", L"Error", MB_OK);
		return false;
	}

	return true;
	
}

bool DOFShaderClass::PreRender(D3DClass* i_device)
{
	m_OriginalTexture->SetRenderTarget(i_device->GetDeviceContext());
	m_OriginalTexture->ClearRenderTarget(i_device->GetDeviceContext(),0.0,0.0,0.0,0.0);
	return true;
}

bool DOFShaderClass::Render(D3DClass* i_device, D3DXMATRIX& worldMatrix, D3DXMATRIX& viewMatrix, D3DXMATRIX& projectionMatrix)
{
	/*DOF SHADER*/
	/* set render to texture and apply Blur*/
	/* set quad in front of screen and render final texture mergin the blurred and original texture in base of each pixel depth*/
	/*END DOF SHADER*/
	
	m_HorizontalBlurredTexture->GetOrthoMatrix(projectionMatrix);
	i_device->TurnZBufferOff();

	i_device->SetActiveRenderTarget(m_HorizontalBlurredTexture->GetRenderTarget());
	m_HorizontalBlurredTexture->ClearRenderTarget(i_device->GetDeviceContext(),0.0,0.0,0.0,0.0);
	m_FullScreenWindow->Render(i_device->GetDeviceContext());
	m_HorizontalBlurShader->Render(i_device->GetDeviceContext(), m_FullScreenWindow->GetIndexCount(),worldMatrix,viewMatrix,projectionMatrix,m_OriginalTexture->GetShaderResourceView());

	i_device->SetActiveRenderTarget(m_VerticalBlurredTexture->GetRenderTarget());
	m_VerticalBlurredTexture->ClearRenderTarget(i_device->GetDeviceContext(),0.0,0.0,0.0,0.0);
	m_FullScreenWindow->Render(i_device->GetDeviceContext());
	m_VerticalBlurShader->Render(i_device->GetDeviceContext(), m_FullScreenWindow->GetIndexCount(),worldMatrix,viewMatrix,projectionMatrix,m_HorizontalBlurredTexture->GetShaderResourceView());

	i_device->SetBackBufferRenderTarget();
	i_device->ResetViewport();
	m_FullScreenWindow->Render(i_device->GetDeviceContext());

	m_MergeTextureShader->Render(i_device->GetDeviceContext(), m_FullScreenWindow->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,m_OriginalTexture->GetShaderResourceView(), m_VerticalBlurredTexture->GetShaderResourceView(), m_OriginalTexture->GetDepthShaderResourceView());
	
	i_device->TurnZBufferOn();

	return true;
}

bool DOFShaderClass::PostRender(D3DClass* i_device)
{
	i_device->SetBackBufferRenderTarget();
	i_device->ResetViewport();
	return true;
}

void DOFShaderClass::ShutdownShader()
{
	delete m_HorizontalBlurShader;
	delete m_VerticalBlurShader;
	delete m_MergeTextureShader;

	delete m_OriginalTexture,
	delete m_HorizontalBlurredTexture;
	delete m_VerticalBlurredTexture;
	delete m_FinalTexture;
	delete m_FullScreenWindow;
}

DOFShaderClass::~DOFShaderClass()
{
	ShutdownShader();
}